package cn.maiyar.mybatis.config;

import cn.maiyar.mybatis.metadata.CustomMetaObjectHandler;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import cn.maiyar.mybatis.MybatisPlusAutoFillProperties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.EnumTypeHandler;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * mybatis-plus 默认的配置
 *
 * @author c.c
 */
@Slf4j
@Configuration
@AllArgsConstructor
@MapperScan("cn.maiyar.**.mapper*")
@EnableConfigurationProperties(MybatisPlusAutoFillProperties.class)
public class MybatisPlusConfig {

    /*** 单页分页条数限制(默认无限制,参见 插件#handlerLimit 方法) */
    private static final Long MAX_LIMIT = 10000L;

    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,
     * 需要设置 MybatisConfiguration#useDeprecatedExecutor = false
     * 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor paginationInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        paginationInnerInterceptor.setMaxLimit(MAX_LIMIT);
        paginationInnerInterceptor.setOptimizeJoin(false);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        // 防止全表更新与删除插件
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        // 乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

    /**
     * 自动填充数据
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(CustomMetaObjectHandler.class)
    @ConditionalOnProperty(prefix = "mybatis-plus.auto-fill", name = "enabled", havingValue = "true", matchIfMissing = true)
    public CustomMetaObjectHandler mateMetaObjectHandler(MybatisPlusAutoFillProperties autoFillProperties) {
        return new CustomMetaObjectHandler(autoFillProperties);
    }

    /**
     * IEnum 枚举配置
     */
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return new MybatisPlusCustomizers();
    }

    /**
     * 自定义配置
     */
    public static class MybatisPlusCustomizers implements ConfigurationCustomizer {

        @Override
        public void customize(MybatisConfiguration configuration) {
            configuration.setDefaultEnumTypeHandler(EnumTypeHandler.class);
        }
    }
}
